/******************************************************************************
 * Copyright 2023 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/canbus_vehicle/x3epro/protocol/vehicle_vin_501.h"

#include "glog/logging.h"

#include "modules/drivers/canbus/common/byte.h"
#include "modules/drivers/canbus/common/canbus_consts.h"

namespace apollo {
namespace canbus {
namespace x3epro {

using ::apollo::drivers::canbus::Byte;

Vehiclevin501::Vehiclevin501() {}
const int32_t Vehiclevin501::ID = 0x501;

void Vehiclevin501::Parse(const std::uint8_t* bytes, int32_t length,
                          X3epro* chassis) const {
  chassis->mutable_vehicle_vin_501()->set_serial_number(
      serial_number(bytes, length));
  switch (chassis->vehicle_vin_501().serial_number()) {
    case 1:
      chassis->mutable_vehicle_vin_501()->set_vin_ascii_1(
          vin_ascii(bytes, length));
      break;
    case 2:
      chassis->mutable_vehicle_vin_501()->set_vin_ascii_2(
          vin_ascii(bytes, length));
      break;
    case 3:
      chassis->mutable_vehicle_vin_501()->set_vin_ascii_3(
          vin_ascii(bytes, length).substr(0, 3));
      break;
    default:
      break;
  }
}

// config detail: {'bit': 7, 'is_signed_var': False, 'len': 8, 'name':
// 'serial_number', 'offset': 0.0, 'order': 'motorola', 'physical_range':
// '[0|0]', 'physical_unit': 'bit', 'precision': 1.0, 'type': 'int'}
int Vehiclevin501::serial_number(const std::uint8_t* bytes,
                                 int32_t length) const {
  Byte t0(bytes + 0);
  int32_t x = t0.get_byte(0, 8);

  int ret = x;
  return ret;
}
// config detail: {'bit': 15, 'is_signed_var': False, 'len': 56, 'name':
// 'VIN_ASCII', 'offset': 0.0, 'order': 'motorola', 'physical_range': '[0|0]',
// 'physical_unit': 'bit', 'precision': 1.0, 'type': 'uint8_t*'}
std::string Vehiclevin501::vin_ascii(const std::uint8_t* bytes,
                                     const int32_t length) const {
  Byte t0(bytes + 1);
  int32_t x0 = t0.get_byte(0, 8);
  Byte t1(bytes + 2);
  int32_t x1 = t1.get_byte(0, 8);
  Byte t2(bytes + 3);
  int32_t x2 = t2.get_byte(0, 8);
  Byte t3(bytes + 4);
  int32_t x3 = t3.get_byte(0, 8);
  Byte t4(bytes + 5);
  int32_t x4 = t4.get_byte(0, 8);
  Byte t5(bytes + 6);
  int32_t x5 = t5.get_byte(0, 8);
  Byte t6(bytes + 7);
  int32_t x6 = t6.get_byte(0, 8);

  std::string ret = "";
  ret += static_cast<char>(x0);
  ret += static_cast<char>(x1);
  ret += static_cast<char>(x2);
  ret += static_cast<char>(x3);
  ret += static_cast<char>(x4);
  ret += static_cast<char>(x5);
  ret += static_cast<char>(x6);

  return ret;
}

}  // namespace x3epro
}  // namespace canbus
}  // namespace apollo
